<?php
/**
 * Created by Administrator
 * User: longli
 * VX: isa1589518286
 * Date: 2020/08/19
 * Time: 10:28
 * @link http://www.lmterp.cn
 */

namespace app\common\service\export;

use app\common\library\FileExcel;
use app\common\service\BaseService;
use Env;

/**
 * 数据导出基类
 * Class BaseExport
 * @package app\common\service\export
 */
abstract class BaseExport extends BaseService
{
    /**
     * 导出文件名前缀
     * @var string
     */
    protected $prefix = "";

    /**
     * 导出数据表头
     * @return array
     * @date 2020/08/24
     * @author longli
     */
    abstract public function getheader();

    /**
     * 导出数据内容
     * @param array $condition 获取数据条件
     * @return array
     * @date 2020/08/24
     * @author longli
     */
    abstract public function getData($condition = []);

    /**
     * 导出 CSV
     * @param array $condition 导出条件
     * @date 2020/08/24
     * @author longli
     */
    public function runCSV($condition = [])
    {
        $data = $this->getData($condition);
        $header = array_values($this->getheader());
        $path = Env::get("runtime_path") . "export/" . date("Y/m");
        $fileName = $path . "/" . $this->getFileName(). ".csv";
        if(!is_dir($path)) mkdir($path, 0777, true);
        $fp = fopen($fileName, 'a');
        mb_convert_variables('GBK', 'UTF-8', $header);
        fputcsv($fp, $header);
        foreach($data as $item)
        {
            mb_convert_variables('GBK', 'UTF-8', $item);
            fputcsv($fp, array_values($item));
        }
        fclose($fp);
        return $fileName;
    }

    /**
     * 导出 excel
     * @param array $condition 导出条件
     * @return string
     * @date 2020/08/24
     * @author longli
     */
    public function runExcel($condition = [])
    {
        $excel = new FileExcel(Env::get("runtime_path") . "export/" . date("Y/m"));
        return $excel->write(array_values($this->getheader()), $this->getData($condition), $this->getFileName() . ".xlsx");
    }

    /**
     * 下载文件
     * @param string $filePath 文件所在路径
     * @param bool $isRemove 是否删除原文件，默认不删除
     * @return bool
     * @date 2020/09/03
     * @author longli
     */
    public static function download($filePath = '', $isRemove = false)
    {
        if(!is_file($filePath)) return false;
        set_time_limit(0);
        // 打开文件
        $fp = fopen($filePath, "rb");
        $size = filesize($filePath);
        Header("Content-type: application/octet-stream");
        Header("Accept-Ranges: bytes");
        Header("Accept-Length: $size");
        Header("Content-Disposition: attachment; filename=" . basename($filePath));
        $readBuffer = 4096;
        while(!feof($fp)) echo fread($fp, $readBuffer);
        fclose($fp);
        if($isRemove) unlink($filePath);
        die;
    }

    /**
     * 解析需要导出的字段
     * @date 2020/09/10
     * @return array
     * @author longli
     */
    protected function getField()
    {
        $ret = [];
        foreach(array_keys($this->getHeader()) as $i => $key)
        {
            $temp = explode('.', $key);
            if(count($temp) == 2)
            {
                $pre = $temp[0];
                if(!isset($ret[$pre])) $ret[$pre] = [];
                $ret[$pre] += [$temp[1] => $key];
            }
        }
        return $ret;
    }

    /**
     * 解析查询条件
     * @param array $condition 查询条件
     * @return array
     * @date 2020/09/10
     * @author longli
     */
    protected function parseWhere($condition = [])
    {
        $ret = [];
        foreach(array_keys($this->getHeader()) as $key)
        {
            $temp = explode('.', $key);
            if(!isset($ret[$temp[0]])) $ret[$temp[0]] = [];
        }
        foreach($condition as $item)
        {
            $temp = explode('.', $item[0]);
            if(count($temp) == 2)
            {
                $pre = $temp[0];
                $item[0] = $temp[1];
                $ret[$pre][] = $item;
            }
            else
            {
                $ret['other'][] = $item;
            }
        }
        return $ret;
    }

    /**
     * 对导出数据进行排序输出
     * @param array $rows 结果集
     * @date 2020/09/10
     * @author longli
     */
    protected function sortData(& $rows = [])
    {
        $keys = array_keys($this->getHeader());
        foreach($rows as $rk => $rv)
        {
            $t = [];
            foreach($keys as $key)
            {
                $t[$key] = isset($rv[$key]) ? $rv[$key] : '';
            }
            $rows[$rk] = $t;
        }
    }

    /**
     * 获取文件名
     * @return string
     * @date 2020/08/24
     * @author longli
     */
    protected function getFileName()
    {
        return (!empty($this->prefix) ? $this->prefix . "-" : "") . date("YmdHis");
    }
}